package com.um.jdy.platform.user.manager;

import cn.dev33.satoken.stp.StpUtil;
import com.um.jdy.common.base.enums.YesOrNo;
import com.um.jdy.common.platform.code.LoginCode;
import com.um.jdy.common.platform.code.PartnersCode;
import com.um.jdy.common.platform.code.PlatformCode;
import com.um.jdy.common.platform.entity.po.*;
import com.um.jdy.common.platform.entity.vo.CompanyUserVO;
import com.um.jdy.common.platform.enums.PlatformEnum;
import com.um.jdy.common.platform.service.*;
import com.um.jdy.common.system.enums.LoginType;
import com.um.jdy.common.commons.properties.HshChargingProperties;
import com.um.jdy.platform.platform.entity.vo.CompanyMenuNode;
import com.um.jdy.platform.platform.entity.vo.CompanyMenuTreeNode;
import com.um.jdy.platform.platform.service.PlatformMenuTreeService;
import com.um.jdy.platform.system.service.PermissionService;
import com.um.jdy.platform.user.entity.dto.UserEditDTO;
import com.um.jdy.platform.user.entity.vo.PackageVO;
import com.um.jdy.platform.user.service.SessionUserService;
import com.um.springboot.starter.code.CommonCode;
import com.um.springboot.starter.constants.Constants;
import com.um.springboot.starter.exception.ServiceException;
import com.um.springboot.starter.helper.SessionHelper;
import com.um.springboot.starter.orm.entity.Response;
import com.um.springboot.starter.orm.manager.BaseManager;
import com.um.springboot.starter.properties.HshProperties;
import com.um.springboot.starter.service.TokenService;
import com.um.springboot.starter.utils.DateUtil;
import com.um.springboot.starter.utils.DesEncrypter;
import com.um.springboot.starter.utils.RSAUtil;
import com.um.springboot.starter.utils.UMBeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;


/**
 * 管理类：手机
 *
 * @author cs
 * 日期 2023/5/23
 * 版权所有 广州优匠科技有限公司
 */
@Component
public class UserManager extends BaseManager<CompanyService> {

    @Autowired
    private CompanyUserService companyUserService;

    @Autowired
    protected SessionHelper sessionHelper;

    @Autowired
    TokenService tokenService;

    @Autowired
    SessionUserService sessionUserService;

    @Autowired
    CompanyMenuService companyMenuService;

    @Autowired
    CompanyUserLogService companyUserLogService;

    @Autowired
    PlatformMenuTreeService platformMenuTreeService;

    @Autowired
    AppPackageService appPackageService;

    @Autowired
    HshProperties hshProperties;

    @Autowired
    HshChargingProperties hshChargingProperties;

    @Autowired
    PermissionService permissionService;


    public Response signin(String username, String password) {

        password = RSAUtil.simpleDecrypt(password);

        CompanyUser companyUser = companyUserService.getEntity("mobile", username);
        if (companyUser == null) {
            throw new ServiceException(LoginCode.LoginError);
        }
        //校验密码
        String pwd = companyUser.getPassword();
        DesEncrypter des = new DesEncrypter(DesEncrypter.CD_KEY);
        String pwd2 = des.decrypt(pwd);
        if (!password.equals(pwd2)) {
            throw new ServiceException(LoginCode.LoginError);
        }

        if(companyUser.getIsEnable().equals(YesOrNo.No.name())){
            throw new ServiceException(LoginCode.AccountDisabled);
        }

        //记录登录日志
        CompanyUserLog loginLog = new CompanyUserLog();
        loginLog.setPlatformCompanyUserId(companyUser.getPlatformCompanyUserId());
        loginLog.setComId(companyUser.getComId());
        loginLog.setLoginDate(new Date());
        loginLog.setAction(LoginType.SignIn.getKey());
        loginLog.setUserNo(companyUser.getMobile());
        loginLog.setUserName(companyUser.getName());
        companyUserLogService.add(loginLog);

        return signinSuccess(companyUser);
    }

    /**
     * 登录成功
     */
    public Response signinSuccess(CompanyUser companyUser) {
        String token = null;
        if ("token".equals(hshProperties.getConfig().getSessionType())) {
            token = tokenService.generate(companyUser.getPlatformCompanyUserId());
        } else if ("sa-token".equals(hshProperties.getConfig().getSessionType())) {
            StpUtil.login(companyUser.getPlatformCompanyUserId());
            token = StpUtil.getTokenValue();
        } else {
            sessionHelper.setAttribute(Constants.SESSION_USER, companyUser);
        }
        getUserMenu();
        return Response.success(token);
    }

    public Response signout() {
        CompanyUser companyUser = sessionUserService.getTokenUser();
        if(companyUser == null){
            return Response.failed(CommonCode.LoginExpired);
        }

        //记录登录日志
        CompanyUserLog loginLog = new CompanyUserLog();
        loginLog.setPlatformCompanyUserId(companyUser.getPlatformCompanyUserId());
        loginLog.setComId(companyUser.getComId());
        loginLog.setLoginDate(new Date());
        loginLog.setAction(LoginType.SignOut.getKey());
        loginLog.setUserNo(companyUser.getMobile());
        loginLog.setUserName(companyUser.getName());
        companyUserLogService.add(loginLog);

        if ("token".equals(hshProperties.getConfig().getSessionType())) {
            tokenService.remove(companyUser.getPlatformCompanyUserId());
        } else if ("sa-token".equals(hshProperties.getConfig().getSessionType())) {
            StpUtil.logout();
        } else {
            sessionHelper.removeAttribute(Constants.SESSION_USER);
        }
        return Response.success();
    }

    public CompanyUserVO get() {
        CompanyUser companyUser = sessionUserService.getTokenUser();
        return UMBeanUtils.copyBean(companyUser, CompanyUserVO.class);
    }


    public Response<PackageVO> getAppPackage(){
        AppPackage appPackage = appPackageService.getEntity("com_id",getComId());
        if(appPackage == null){
            throw new ServiceException(PlatformCode.PackageNotExist);
        }


        PackageVO packageVO = UMBeanUtils.copyBean(appPackage,PackageVO.class);


        if(hshChargingProperties.isLimitDeviceDate()) {
            int days = DateUtil.daysBetween(new Date(),appPackage.getEndDate());
            if (days > 30) {
                packageVO.setStatus(PlatformEnum.PackageStatus.Normal.name());
            } else if (days <= 30 && days > 0) {
                packageVO.setStatus(PlatformEnum.PackageStatus.Warn.name());
                packageVO.setTips("平台到期剩余<span class='remain-days'>" + days + "</span>天");
                packageVO.setActionTips("去续费");
            } else {
                packageVO.setStatus(PlatformEnum.PackageStatus.Expired.name());
                packageVO.setTips("平台已过期");
                packageVO.setActionTips("去续费");
            }

            packageVO.setDays(days);
            packageVO.setPackageName("包年");
            packageVO.setLimitDays(YesOrNo.Yes.name());
        }else{
            packageVO.setStatus(PlatformEnum.PackageStatus.Normal.name());
            packageVO.setDays(1000);
            packageVO.setPackageName("包年");
            packageVO.setLimitDays(YesOrNo.No.name());
        }

        return Response.success(packageVO);
    }

    /**
     * 读取用户的菜单
     * @return
     */
    public Response<CompanyMenuTreeNode> getUserMenu(){
        List<CompanyMenu> listMenu;
        CompanyUser companyUser = sessionUserService.getTokenUser();
        if(companyUser == null){
            return Response.failed(CommonCode.LoginExpired);
        }
        String userId = companyUser.getPlatformCompanyUserId();

        if(YesOrNo.Yes.name().equals(companyUser.getIsMaster())) {
            listMenu = companyMenuService.getRows(new String[]{}, new Object[]{}, "sort_no", "asc");
        }else{
            listMenu = companyMenuService.getViewModelList("platform_get_user_menu",CompanyMenu.class,new Object[]{userId,getComId()});
        }

        AppPackage appPackage = appPackageService.getEntity("com_id",getComId());

        //没有充电宝权限
        if(YesOrNo.No.name().equals(appPackage.getOpenPb()) || isExpire(appPackage.getDevicePbTime())) {
            listMenu = listMenu.stream().filter(item -> !"PowerBank".equals(item.getLinkUrl()))
                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_pb_storage".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_pb_merchant".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_pb_running".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
            //押金订单
            listMenu = listMenu.stream().filter(item -> !"main.order_deposit".equals(item.getLinkUrl()))
                    .collect(Collectors.toList());
            //租借设置
            listMenu = listMenu.stream().filter(item -> !"main.setting_rent".equals(item.getLinkUrl()))
                    .collect(Collectors.toList());
            //免押设置
            listMenu = listMenu.stream().filter(item -> !"main.setting_deposit_free".equals(item.getLinkUrl()))
                    .collect(Collectors.toList());
        }

        //没有两轮桩权限
        if(YesOrNo.No.name().equals(appPackage.getOpenEb()) || isExpire(appPackage.getDeviceEbTime())) {
            listMenu = listMenu.stream().filter(item -> !"EBike".equals(item.getLinkUrl()))
                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_eb_storage".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_eb_merchant".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_eb_running".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
        }

        //没有换电柜
        if(YesOrNo.No.name().equals(appPackage.getOpenBsb()) || isExpire(appPackage.getDeviceBsbTime())) {
            listMenu = listMenu.stream().filter(item -> !"Bsb".equals(item.getLinkUrl()))
                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_eb_storage".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_eb_merchant".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_eb_running".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
        }

        //没有充电柜
        if(YesOrNo.No.name().equals(appPackage.getOpenEbox()) || isExpire(appPackage.getDeviceEboxTime())) {
            listMenu = listMenu.stream().filter(item -> !"EBox".equals(item.getLinkUrl()))
                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_eb_storage".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_eb_merchant".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_eb_running".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
        }

        //没有汽车桩权限
        if(YesOrNo.No.name().equals(appPackage.getOpenEv()) || isExpire(appPackage.getDeviceEvTime())) {
            listMenu = listMenu.stream().filter(item -> !"EVCharger".equals(item.getLinkUrl()))
                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_ev_storage".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_ev_merchant".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
//            listMenu = listMenu.stream().filter(item -> !"main.device_ev_running".equals(item.getLinkUrl()))
//                    .collect(Collectors.toList());
        }

        //没有商城权限
        if(YesOrNo.No.name().equals(appPackage.getOpenMall()) || isExpire(appPackage.getMallTime())) {
            listMenu = listMenu.stream().filter(item -> !"Mall".equals(item.getLinkUrl()))
                    .collect(Collectors.toList());

            //商城入口设置
            listMenu = listMenu.stream().filter(item -> !"main.setting_mall".equals(item.getLinkUrl()))
                    .collect(Collectors.toList());
        }

        //非独立部署，不需要开发设置菜单
        if(hshChargingProperties.isLimitDeviceNum()) {
            listMenu = listMenu.stream().filter(item -> !"开发设置".equals(item.getLinkUrl()))
                    .collect(Collectors.toList());
        }

        // 更新权限列表
        permissionService.loadPermissionList(userId, listMenu);

        List<CompanyMenuNode> listNode = UMBeanUtils.copyBeanList(listMenu,CompanyMenuNode.class);
        List<CompanyMenuTreeNode> nodes = platformMenuTreeService.toTreeNodeList(listNode);
        CompanyMenuTreeNode menuTreeNode = platformMenuTreeService.listToTreeNode("0", nodes);
        return Response.success(Optional.ofNullable(menuTreeNode).orElseGet(CompanyMenuTreeNode::new));
    }

    /**
     * 判断某一种设备套餐是否过期
     * @param expireDate
     * @return
     */
    private boolean isExpire(Date expireDate){
        if(!hshChargingProperties.isLimitDeviceDate())
            return false;

        if(expireDate == null)
            return false;

        if(DateUtil.daysBetween(new Date(),expireDate) > 0){
            return false;
        }

        return true;
    }

    /**
     * 修改密码
     *
     * @param oldPassword
     * @param password
     * @return
     */
    public boolean editPassword(String oldPassword, String password) {
        CompanyUser companyUser = sessionUserService.getTokenUser();
        if (companyUser == null) {
            throw new ServiceException(CommonCode.LoginExpired);
        }

        password = RSAUtil.simpleDecrypt(password);
        oldPassword = RSAUtil.simpleDecrypt(oldPassword);

        String pwd = companyUser.getPassword();
        DesEncrypter des = new DesEncrypter(DesEncrypter.CD_KEY);
        String pwd2 = des.decrypt(pwd);
        if (!oldPassword.equals(pwd2)) {
            throw new ServiceException(PartnersCode.OldPasswordError);
        }

        if (password.equals(pwd2)) {
            throw new ServiceException(PartnersCode.PwdSame);
        }

        companyUser.setPassword(des.encrypt(password));
        return companyUserService.update(companyUser);
    }

    /**
     * 修改用户资料
     * @param dto
     * @return
     */
    public CompanyUserVO edit(UserEditDTO dto){

        CompanyUser companyUser = companyUserService.getEntity(sessionUserService.getTokenUserId());
        if(companyUser == null){
            throw new ServiceException(CommonCode.LoginExpired);
        }

        companyUser.setLinkman(dto.getLinkman());
        companyUser.setPhone(dto.getPhone());
        companyUser.setLogo(dto.getLogo());
        companyUser.setName(dto.getName());
        companyUserService.update(companyUser);

        return UMBeanUtils.copyBean(companyUser,CompanyUserVO.class);
    }
}
